package org.gzc.queue;

import java.util.concurrent.ArrayBlockingQueue;

/**
 * @Description: 队列的实现2
 * @Author: guozongchao
 * @Date: 2020/8/2 13:21
 */
public class CircleArrayQueue2<T> {
    private int capacity;   //队列容量
    private Object[] items;     //存放队列元素
    private int nextPutIndex; //下一个入队的下标
    private int nextGetIndex;  //下一个出队的下标
    private int count;  //队列元素个数


    public CircleArrayQueue2(int capacity) {
        this.capacity = capacity;
        this.items = new Object[capacity];
        this.count = 0;
        this.nextPutIndex = 0;
        this.nextGetIndex = 0;
    }

    //检查元素是否空
    private void checkNotNull(T item) {
        if (item == null) {
            Class<?> aClass = item.getClass();
            throw new NullPointerException("[" + aClass.getName() + "]:空指针异常");
        }
    }

    //判断是否为空队列
    public boolean isEmpty() {
        return count==0;
    }

    //判断队列是否为满
    public boolean isFull() {
        return count == capacity;
    }

    //入队
    public void add(T item) {
        checkNotNull(item);
        if (isFull()) {
            throw new RuntimeException("队列已满");
        }
        items[nextPutIndex++]=item;
        count++;
        if (nextPutIndex == capacity) {
            nextPutIndex=0;
        }
    }

    // 出队
    public T get() {
        if (isEmpty()) {
            throw new RuntimeException("队列没有数据");
        }
        T item = (T) items[nextGetIndex++];
        if (nextGetIndex == capacity) {
            nextGetIndex=0;
        }
        count--;
        return item;
    }

    // 获取队列头，但不出队
    public T getHeadItem() {
        if (isEmpty()) {
            throw new RuntimeException("队列没有数据");
        }
        return (T) items[nextGetIndex];
    }

    // 遍历队列元素,仅针对基本数据类型和字符串类型元素
    public void show() {
        System.out.print("[当前队列共有"+count+"个元素]<----\t");
        for (int i = nextGetIndex; i < (nextGetIndex + count); i++) {
            System.out.print("["+items[i%capacity]+"]\t");
        }
        System.out.println("<----");
    }

    // 获取队列元素个数
    public int size() {
        return count;
    }
}
